package com.sie.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sie.entity.*;
import com.sie.mapper.EmpMapper;
import com.sie.mapper.LoginMapper;
import com.sie.mapper.RoleMapper;
import com.sie.service.EmpService;
import com.sie.util.AsdUtils;
import com.sie.util.DataUtil;
import com.sie.util.RegularExpressionUtil;
import com.sie.util.ReslUtil;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 用户服务实现类
 */
@Service
@Transactional(rollbackFor = Exception.class)
@SuppressWarnings("all")
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private RoleMapper roleMapper;

    /**
     * 分页查询用户
     *
     * @param request
     * @param viewEmp
     * @param bigTime
     * @param small
     * @param page
     * @param size
     * @return
     */
    @Override
    public Map findByPage(HttpServletRequest request, ViewEmp viewEmp, String bigTime, String small, String page, String size) {
        if (!AsdUtils.asd(request, "查询用户")) {
            return ReslUtil.fail();
        }
//        非空排除
        if (viewEmp == null) {
            viewEmp = new ViewEmp();
        }
//        分页参数处理
        int pageNum, pageSize;
        try {
            pageNum = Integer.parseInt(page);
            pageSize = Integer.parseInt(size);
        } catch (Exception e) {
            pageNum = 1;
            pageSize = 5;
        }
//分页查询
        PageHelper.startPage(pageNum, pageSize);
        List<ViewEmp> byPage = empMapper.findByPage(viewEmp, bigTime, small);
        PageInfo<ViewEmp> viewEmpPageInfo = new PageInfo<>(byPage);
        List<ViewEmp> list = viewEmpPageInfo.getList();
        ArrayList<Role> validRole = new ArrayList<>();
//        获取所有有效角色
        for (ViewEmp e : list) {
            validRole.clear();
            List<Role> roles = roleMapper.findRoles(e.getEmpId());
            for (Role role : roles) {
                role.setRoleName(role.getRoleName().substring(5));
                if (role.getRoleStatus().equals("1")) {
                    validRole.add(role);
                }
            }
            e.setRoles((List<Role>) validRole.clone());
        }
//        包装返回信息
        Map success = ReslUtil.success();
        success.put("data", list);
        success.put("total", viewEmpPageInfo.getTotal());
        success.put("pagesize", viewEmpPageInfo.getPageSize());
        DataUtil.list = list;
        return success;
    }

    /**
     * 用户修改
     *
     * @param entity
     * @param password
     * @param request
     * @return
     */
    @Override
    public Map update(ViewEmp entity, String password, HttpServletRequest request) {
        if (!AsdUtils.asd(request, "修改用户") || entity == null) {
            return ReslUtil.fail();
        }
//        获取系统当前时间
        entity.setEmpLastTime(LocalDateTime.now().toString().split("T")[0]);
        //根据用户名查找对应的员工信息并获取修改员工的主键id
        ViewEmpLogin loginEntity = empMapper.findByNameToEmp(entity.getLoginName());
        entity.setEmpId(loginEntity.getEmpId());
//        修改第一张员工表
        Integer update = empMapper.update(entity);
        if (password != null && password.length() != 0) {
//        获取新的盐
            String slat = RandomUtil.randomString(3);
//        获取密文
            String ciphertext = DigestUtils.md5DigestAsHex(password.concat(slat).getBytes());
//        修改第二张登录信息表
            int i = loginMapper.updatePassword(entity.getLoginName(), ciphertext, slat);
            if (update != 1 || i != 1) {
                return ReslUtil.fail();
            }
            return ReslUtil.success();
        }
        if (update == 1)
            return ReslUtil.success();
        return ReslUtil.success();
    }

    /**
     * 登录名查重
     *
     * @param loginName
     * @return
     */
    @Override
    public Map loginNameDetection(String loginName) {
        //非空判断
        if (loginName == null || loginName.isEmpty()) {
            return ReslUtil.fail();
        }
//        查询是否存在
        Login viewEmpLogin = loginMapper.findGetName(loginName);
        if (viewEmpLogin == null) {
            return ReslUtil.success();
        }
        Map fail = ReslUtil.fail();
        fail.put("ps", "用户名已存在");
        return fail;
    }

    /**
     * 新增用户
     *
     * @param entity
     * @param password
     * @param request
     * @return
     */
    @Override
    public Map addEmp(ViewEmp entity, String password, HttpServletRequest request) {
        if (!AsdUtils.asd(request, "新增用户")) {
            return ReslUtil.fail();
        }
//        获取系统当前时间
        String t = LocalDateTime.now().toString().split("T")[0];
//        初始化创建时间和最后修改时间
        entity.setEmpCreateTime(t);
        entity.setEmpLastTime(t);
        //添加第一张员工表并获取主键
        int i = empMapper.addEmp(entity);
        if (i == 1) {
//            获取盐
            String salt = RandomUtil.randomString(3);
//            获取密文
            String ciphertext = DigestUtils.md5DigestAsHex(password.concat(salt).getBytes());
//            添加第二张login表并获取主键
            Login login = new Login(null, entity.getLoginName(), ciphertext, salt);
            int insert = loginMapper.addLogin(login);
            if (insert == 1) {
//                添加第三张login_emp中间表
                int flag = loginMapper.insert(new EmpLogin(null, Integer.parseInt(entity.getEmpId()), login.getLoginId()));
                if (flag == 1) {
                    return ReslUtil.success();
                }
            } else {
                return ReslUtil.fail();
            }
        }
        return ReslUtil.fail();
    }

    /**
     * 表格批量插入用户
     *
     * @param file
     * @param request
     * @return
     */
    @Override
    public Map addExcel(MultipartFile file, HttpServletRequest request) {
        if (!AsdUtils.asd(request, "新增用户")) {
            return ReslUtil.fail();
        }
        if (file == null) {
            Map fail = ReslUtil.fail();
            fail.put("ps", "文件为空");
            return fail;
        }
//        获取文件名称
        String name = file.getOriginalFilename();
//        判断文件格式是否正确
        if (name.endsWith(".xlsx")) {
//            声明excel对象
            XSSFWorkbook workbook = null;
//        获取系统时间
            String time = LocalDateTime.now().toString().split("T")[0];
//            创建两个记录集合
            Set successArr = new HashSet<String>();
            Set failArr = new HashSet<String>();
            try {
//                获取文件输入流
                InputStream inputStream = file.getInputStream();
//                获取excel对象
                workbook = new XSSFWorkbook(inputStream);
//                获取第一张表格对象
                XSSFSheet sheetAt = workbook.getSheetAt(0);
                XSSFRow he = sheetAt.getRow(0);
                String stringCellValue = he.getCell(0).getStringCellValue();
                String stringCellValue1 = he.getCell(8).getStringCellValue();
                if (!("员工姓名".equals(stringCellValue) && "登录账号".equals(stringCellValue1))) {
                    Map fail = ReslUtil.fail();
                    fail.put("ps", "文件格式错误！");
                    return fail;
                }
//                获取有效记录数以及声明成功和失败的个数
                int total = sheetAt.getLastRowNum(), success = 0, fail = 0;
                for (int i = 0; i < total; i++) {
                    XSSFRow row = sheetAt.getRow(i + 1);
                    row.forEach(e -> {
                        e.setCellType(CellType.STRING);
                    });
                    if ((Boolean) loginNameDetection(row.getCell(8).getStringCellValue()).get("res")) {
                        String sex = "";
                        String status = "";
                        if ("男".equals(row.getCell(1).getStringCellValue())) {
                            sex = "1";
                        } else {
                            sex = "0";
                        }
                        if ("有效".equals(row.getCell(4).getStringCellValue())) {
                            status = "1";
                        } else {
                            status = "0";
                        }
                        //获取对象
                        ViewEmp viewEmp = new ViewEmp(null, row.getCell(0).getStringCellValue(), sex, row.getCell(2).getStringCellValue()
                                , row.getCell(3).getStringCellValue(), status, row.getCell(5).getStringCellValue(),
                                row.getCell(6).getStringCellValue(), row.getCell(7).getStringCellValue(), time, time, row.getCell(8).getStringCellValue(), null, null);
                        int lo = 0, en = 0, insert = 0;
                        if (empMapper.findByNameToEmp(viewEmp.getLoginName()) == null && RegularExpressionUtil.empRegular(viewEmp)) {
                            en = empMapper.addEmp(viewEmp);
                            String salt = RandomUtil.randomString(3);
                            String ciphertext = DigestUtils.md5DigestAsHex((row.getCell(9).getStringCellValue() + salt).getBytes());
                            Login login = new Login(null, viewEmp.getLoginName(), ciphertext, salt);
                            lo = loginMapper.addLogin(login);
                            insert = loginMapper.insert(new EmpLogin(null, Integer.parseInt(viewEmp.getEmpId()), login.getLoginId()));
                        }
                        if (en == 1 && lo == 1 && insert == 1) {
                            successArr.add(String.valueOf(i + 1));
                            success++;
                        } else {
                            failArr.add(String.valueOf(i + 1));
                            fail++;
                        }
                    } else {
                        failArr.add(String.valueOf(i + 1));
                        fail++;
                    }
                }

//                返回插入信息
                Map successMap = ReslUtil.success();
                successMap.put("successNum", success);
                successMap.put("failNum", fail);
                successMap.put("successArr", successArr);
                successMap.put("failArr", failArr);
                return successMap;
            } catch (Exception e) {
                Map fail = ReslUtil.fail();
                fail.put("ps", "文件模板错误！");
                e.printStackTrace();
                return fail;
            } finally {
                try {
                    assert workbook != null;
                    workbook.close();
                } catch (IOException e) {
                    System.out.println("系统级错误");
                }
            }
        } else {
            Map fail = ReslUtil.fail();
            fail.put("ps", "文件类型错误！");
            return fail;
        }

    }

    /**
     * 删除用户
     * @param id
     * @param request
     * @return
     * @throws SQLException
     */
    @Override
    public Map deleteById(String id, HttpServletRequest request) throws SQLException {
//        权限验证以及超级管理员排除
        if (!AsdUtils.asd(request, "删除用户") || "1".equals(id)) {
            return ReslUtil.fail();
        }
//        查询并排出删除账号本身
        ViewEmp user = (ViewEmp) request.getAttribute("user");
        if (user.getEmpId().equals(id)) {
            return ReslUtil.fail();
        }
//        删除所有该用户信息
        int i = empMapper.deleteById(id);
        EmpLogin loginByEmpId = empMapper.findLoginByEmpId(id);
        int l = loginMapper.delete(loginByEmpId.getLoginId() + "");
        int j = empMapper.deleteIdAndRole(id);
        int k = empMapper.deleteIdAndLogin(id);
        if (i == 1 && l == 1 && j >= 0 && k == 1) {
            return ReslUtil.success();
        } else {
            throw new SQLException();
        }
    }

    /**
     * 批量删除
     * @param list
     * @param request
     * @return
     */
    @Override
    public Map deleteList(List<String> list, HttpServletRequest request) {
        if (!AsdUtils.asd(request, "删除用户")) {
            return ReslUtil.fail();
        }
//        排除删除账号本身
        ViewEmp user = (ViewEmp) request.getAttribute("user");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (iterator.next().equals(user.getEmpId())) {
                iterator.remove();
            }
        }
//        排除删除超级管理员
        list.forEach(e -> {
            if (!e.equals("1")) {
                empMapper.deleteById(e);
                EmpLogin loginByEmpId = empMapper.findLoginByEmpId(e);
                loginMapper.delete(loginByEmpId.getLoginId() + "");
                empMapper.deleteIdAndRole(e);
                empMapper.deleteIdAndLogin(e);
            }
        });
        return ReslUtil.success();
    }
}
